#pragma once
#include <stdint.h>

#include <list>
#include <map>
#include <string>
#include <vector>

#include "../BondMarketStream.h"
#include "IRealTimeDealModel.h"

namespace detail {
class CBondDealJumpList;
class RealTimeDealCache;
class RealTimeDealStat;
class BondKeyDealIndexMap;
class RealTimeDealList {
 protected:
  enum { OBJECT_TAG = 0xf1f2f3f4 };
  typedef int BatchId;
  typedef uint32_t DayType;
  unsigned int m_tag;
  DayType m_day;
  int64_t m_state;
  detail::CBondDealJumpList* m_keys;  // 索引信息,时间新排在前面
  IRecordMap* m_values;  // 具体值信息,map<IndexID,MarketStreamInfo>
  detail::RealTimeDealStat* m_stats;  // 统计信息

  // 每次收取成交记录信息后,会将简单过滤(IsDealValid)后的成交信息
  // 缓存到此缓冲中,此缓冲可以设定一个最大缓存阀值
  // 阀值满之后,会将旧值删除
  detail::RealTimeDealCache* m_cache;  // 命令缓存

  // 存储每个债券对应的最新成交的DealIndex
  // key 为 "%s-%s",szCombBondKey,szCompanyId
  BondKeyDealIndexMap* m_bonds;  //

  bool m_check;  // 动态检查

  std::map<int, int> m_mapversion;  // version
 public:
  RealTimeDealList(DayType day, int64_t state);
  ~RealTimeDealList();

  // 供UI线程来获取一屏幕记录
  int GetRecords(IRealTimeDealModel* keys, int& pos, int count, void* records);
  DayType GetDay() const { return m_day; }

  IRecordMap* GetKeys(std::vector<DealIndex>& keys, bool all = true) const;
  IRecordMap* GetValues();
  detail::RealTimeDealStat* GetStatObject() { return m_stats; }
  bool GetStat(const std::string& bondKey, MarketStreamRec& stat);

  // 供后台线程来导入成交数据信息
  bool IsObjectValid() const;

  bool FindRecord(const char* szBondKey, const char* szListMarket,
                  const char* szCompanyId, MarketStreamInfo& record,
                  time_t t = 0) const;
  bool ScanForRecord(const char* szBondKey, const char* szListedMarket,
                     const char* szCompanyId, time_t t,
                     MarketStreamInfo& record) const;

  MarketStreamInfo* ElementAt(DealIndex key);

  int GetVersion(int companyID) const;

  virtual void InsertDirectly(const MarketStreamInfo& info, uint32_t unDay,
                              int batchid);
};
class MultiDayDealList : public RealTimeDealList {
  uint32_t m_dayBegin;
  uint32_t m_dayEnd;

 public:
  MultiDayDealList(uint32_t dayBegin, uint32_t dayEnd);
  virtual ~MultiDayDealList();

  uint32_t GetDayBegin();
  uint32_t GetDayEnd();
  bool CheckDayRange(uint32_t dayBegin, uint32_t dayEnd);
  void ChangeDayRange(uint32_t beginDay, uint32_t endDay);

  virtual void InsertDirectly(const MarketStreamInfo& info, uint32_t unDay,
                              int batchid) override;
};
}  // namespace detail
